/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.eolwral.osmonitor.misc;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.Html;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.webkit.WebView;
import android.widget.TextView;

import com.eolwral.osmonitor.*;
import com.eolwral.osmonitor.preferences.Preferences;

public class MiscBox extends Activity
{
	private JNIInterface JNILibrary = JNIInterface.getInstance();

	private boolean UseCelsius = true;
	
	private TextView UptimeBox;
	private TextView PowerStatus;
	private TextView PowerTechnology;
	private TextView PowerCapacity;
	private TextView PowerVoltage;
	private TextView PowerCurrent;
	private TextView PowerTemperature;
	private TextView DiskBox;

	// Gesture
	private GestureScroller gestureScanner;
	
	@Override
	public boolean onTouchEvent(MotionEvent me)
	{
		return gestureScanner.onTouchEvent(me);
	}
	
	private Runnable MiscRunnable = new Runnable() {
		public void run() 
		{
			if (JNILibrary.doDataLoad() == 1)
			{ 
				Resources ResourceManager = getApplication().getResources();

				//Calculate the system uptime.
				StringBuilder m_UptimeStr = new StringBuilder();
				long Uptime = android.os.SystemClock.elapsedRealtime();
				int Days    = (int)((Uptime / 1000) / 86400);
				int Hours   = (int)((Uptime / 1000) / 3600 % 24);
				int Minutes = (int)((Uptime / 1000) / 60 % 60);
				int Seconds = (int)((Uptime / 1000) % 60);
				m_UptimeStr.append(ResourceManager.getText(R.string.uptime_text));
				m_UptimeStr.append(": ");
				m_UptimeStr.append(String.format(
					ResourceManager.getText(R.string.uptime_format).toString(),
					Days, Hours, Minutes, Seconds));
				UptimeBox.setText(Html.fromHtml(m_UptimeStr.toString()));

				//Update the battery current draw, if we know of it.
				String batteryCurrent = CommonUtil.ReadFileLine("/sys/devices/platform/htc_battery/battery_curr");
				if (batteryCurrent.length() != 0)
				{
					batteryCurrent = String.format(
						ResourceManager.getText(R.string.units_milliamps).toString(),
						Integer.parseInt(batteryCurrent));
					if (PowerCurrent != null)
						PowerCurrent.setText(batteryCurrent);
				}

				StringBuilder m_DiskStr = new StringBuilder();
				java.text.DecimalFormat DiskFormat = new java.text.DecimalFormat(",###");
				java.text.DecimalFormat UsageFormat = new java.text.DecimalFormat("#.#");
				String DiskTotal = ResourceManager.getText(R.string.disk_total_text).toString();
				String DiskUsed = ResourceManager.getText(R.string.disk_used_text).toString();
				String DiskAvail = ResourceManager.getText(R.string.disk_available_text).toString();
				final String DiskUsageText = "<b>%s</b> &nbsp; %s%% used<br />" +
						"%s: %s K<br />" +
						"%s: %s K<br />" +
						"%s: %s K<br />";
				final String DiskUsageSeparator = "<br />";

				m_DiskStr.append(String.format(DiskUsageText,
					"/system", JNILibrary.GetSystemMemAvail() == 0 ?
						"0" : UsageFormat.format(
							JNILibrary.GetSystemMemUsed() / JNILibrary.GetSystemMemTotal() * 100),
						DiskTotal, DiskFormat.format(JNILibrary.GetSystemMemTotal()),
						DiskUsed, DiskFormat.format(JNILibrary.GetSystemMemUsed()),
						DiskAvail, DiskFormat.format(JNILibrary.GetSystemMemAvail())));
				m_DiskStr.append(DiskUsageSeparator);

				m_DiskStr.append(String.format(DiskUsageText,
						"/data", JNILibrary.GetDataMemAvail() == 0 ?
							"0" : UsageFormat.format(
								JNILibrary.GetDataMemUsed() / JNILibrary.GetDataMemTotal() * 100),
							DiskTotal, DiskFormat.format(JNILibrary.GetDataMemTotal()),
							DiskUsed, DiskFormat.format(JNILibrary.GetDataMemUsed()),
							DiskAvail, DiskFormat.format(JNILibrary.GetDataMemAvail())));
				m_DiskStr.append(DiskUsageSeparator);

				m_DiskStr.append(String.format(DiskUsageText,
						Environment.getExternalStorageDirectory(), JNILibrary.GetSDCardMemAvail() == 0 ?
							"0" : UsageFormat.format(
								JNILibrary.GetSDCardMemUsed() / JNILibrary.GetSDCardMemTotal() * 100),
							DiskTotal, DiskFormat.format(JNILibrary.GetSDCardMemTotal()),
							DiskUsed, DiskFormat.format(JNILibrary.GetSDCardMemUsed()),
							DiskAvail, DiskFormat.format(JNILibrary.GetSDCardMemAvail())));
				m_DiskStr.append(DiskUsageSeparator);

				m_DiskStr.append(String.format(DiskUsageText,
						"/cache", JNILibrary.GetCacheMemAvail() == 0 ?
							"0" : UsageFormat.format(
								JNILibrary.GetCacheMemUsed() / JNILibrary.GetCacheMemTotal() * 100),
							DiskTotal, DiskFormat.format(JNILibrary.GetCacheMemTotal()),
							DiskUsed, DiskFormat.format(JNILibrary.GetCacheMemUsed()),
							DiskAvail, DiskFormat.format(JNILibrary.GetCacheMemAvail())));

				DiskBox.setText(Html.fromHtml(m_DiskStr.toString()));		
			}

			MiscHandler.postDelayed(this, 1000);
		}
	};
	
	Handler MiscHandler = new Handler();

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		setContentView(R.layout.misclayout);

		gestureScanner = new GestureScroller(this, findViewById(R.id.miscview),
				4);

		UptimeBox = (TextView) findViewById(R.id.uptimeText);
		PowerStatus = (TextView) findViewById(R.id.powerStatusText);
		PowerTechnology = (TextView) findViewById(R.id.powerTechnologyText);
		PowerCapacity = (TextView) findViewById(R.id.powerCapacityText);
		PowerVoltage = (TextView) findViewById(R.id.powerVoltageText);
		PowerCurrent = (TextView) findViewById(R.id.powerCurrentText);
		PowerTemperature = (TextView) findViewById(R.id.powerTemperatureText);
		DiskBox = (TextView) findViewById(R.id.diskText);
	}

	private void restorePrefs()
	{
		// load settings
		SharedPreferences settings = PreferenceManager
				.getDefaultSharedPreferences(this);

		if (settings.getBoolean(Preferences.PREF_STATUSBAR, false))
		{
			if (OSMonitorService.getInstance() == null)
				startService(new Intent(this, OSMonitorService.class));
			else
				OSMonitorService.getInstance().Notify();
		}
		else if (OSMonitorService.getInstance() != null)
			OSMonitorService.getInstance().stopSelf();

		UseCelsius = settings.getBoolean(Preferences.PREF_TEMPERATURE, true);
	}

	public boolean onCreateOptionsMenu(Menu optionMenu)
	{
		return true;
	}

	@Override
	protected Dialog onCreateDialog(int id)
	{
		switch (id)
		{
		case 0:
			AlertDialog.Builder HelpWindows = new AlertDialog.Builder(this);
			HelpWindows.setTitle(R.string.app_name);
			HelpWindows.setMessage(R.string.help_info);
			HelpWindows.setPositiveButton(R.string.button_close,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int whichButton)
						{
						}
					});

			WebView HelpView = new WebView(this);
			HelpView.loadUrl("http://wiki.android-os-monitor.googlecode.com/hg/phonehelp.html?r=b1c196ee43855882e59ad5b015b953d62c95729d");
			HelpWindows.setView(HelpView);

			return HelpWindows.create();
		}

		return null;
	}

	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		restorePrefs();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		super.onOptionsItemSelected(item);
		return true;
	}

    @Override
    public void onPause() 
    {
   		stopBatteryMonitor();

    	MiscHandler.removeCallbacks(MiscRunnable);
    	JNILibrary.doTaskStop();
    	super.onPause();
    }

    @Override
    protected void onResume() 
    {    
    	restorePrefs();
    	startBatteryMonitor();
    	
    	JNILibrary.doTaskStart(JNILibrary.doTaskMisc);
    	MiscHandler.post(MiscRunnable);
    	super.onResume();
    }
    
    private void startBatteryMonitor()
    {
    	IntentFilter battFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    	registerReceiver(battReceiver, battFilter);		        		
    }
    
    private void stopBatteryMonitor()
    {
    	unregisterReceiver(battReceiver);
    }

	private BroadcastReceiver battReceiver = new BroadcastReceiver() 
	{
		public void onReceive(Context context, Intent intent)
		{
			Resources ResourceManager = getApplication().getResources();
			if (ResourceManager == null || PowerStatus == null)
				return;

			int rawlevel = intent.getIntExtra("level", -1);
			int scale = intent.getIntExtra("scale", -1);
			int status = intent.getIntExtra("status", -1);
			int health = intent.getIntExtra("health", -1);
			int plugged = intent.getIntExtra("plugged", -1);
			int temperature = intent.getIntExtra("temperature", -1);
			int voltage = intent.getIntExtra("voltage", -1);
			String technology = intent.getStringExtra("technology");
			final String subStatusText = "(%s)";

			//Compute the battery level (as %)
			int level = -1; // percentage, or -1 for unknown
			if (rawlevel > 0 && scale > 0)
			{
				level = (rawlevel * 100) / scale;
			}

			//Build the power status text string.
			StringBuilder powerTextTemplate = new StringBuilder();
			switch (status)
			{
			case BatteryManager.BATTERY_STATUS_UNKNOWN:
				powerTextTemplate.append(
					ResourceManager.getText(
						R.string.battery_status_unknown_text));
				break;
			case BatteryManager.BATTERY_STATUS_CHARGING:
				powerTextTemplate.append(
					ResourceManager.getText(
						R.string.battery_status_charging_text));
				break;
			case BatteryManager.BATTERY_STATUS_DISCHARGING:
				powerTextTemplate.append(
					ResourceManager.getText(
						R.string.battery_status_discharging_text));
				break;
			case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
				powerTextTemplate.append(
					ResourceManager.getText(
						R.string.battery_status_notcharging_text));
				break;
			case BatteryManager.BATTERY_STATUS_FULL:
				powerTextTemplate.append(
					ResourceManager.getText(
						R.string.battery_status_full_text));
				break;
			}
			
			//Charging status
			powerTextTemplate.append(' ');
			if (plugged == BatteryManager.BATTERY_PLUGGED_AC)
				powerTextTemplate.append(
					String.format(subStatusText,
						ResourceManager.getText(R.string.battery_acpower_text)));
			else if (plugged == BatteryManager.BATTERY_PLUGGED_USB)
				powerTextTemplate.append(
					String.format(subStatusText,
						ResourceManager.getText(R.string.battery_usbpower_text)));

			//Battery health
			switch (health)
			{
			case BatteryManager.BATTERY_HEALTH_DEAD:
				powerTextTemplate.append(", ");
				powerTextTemplate.append(
					ResourceManager.getText(
						R.string.battery_health_dead_text));
				break;
			case BatteryManager.BATTERY_HEALTH_GOOD:
				break;
			case BatteryManager.BATTERY_HEALTH_OVERHEAT:
				powerTextTemplate.append(", ");
				powerTextTemplate.append(
					ResourceManager.getText(
						R.string.battery_health_overheat_text));
				break;
			case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
				powerTextTemplate.append(", ");
				powerTextTemplate.append(
					ResourceManager.getText(
						R.string.battery_health_overvoltage_text));
				break;
			case BatteryManager.BATTERY_HEALTH_UNKNOWN:
				powerTextTemplate.append(", ");
				powerTextTemplate.append(
					ResourceManager.getText(
						R.string.battery_health_unknown_text));
				break;
			case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
				powerTextTemplate.append(", ");
				powerTextTemplate.append(
					ResourceManager.getText(
						R.string.battery_health_failure_text));
				break;

			}
			PowerStatus.setText(Html.fromHtml(powerTextTemplate.toString()));
			
			//Set the other fields.
			PowerTechnology.setText(technology);
			PowerCapacity.setText(String.format(
				ResourceManager.getText(R.string.units_percentage).toString(),
				(float)level));
			PowerVoltage.setText(String.format(
				ResourceManager.getText(R.string.units_millivolts).toString(),
				voltage));
			if (UseCelsius)
			{
				PowerTemperature.setText(String.format(
					ResourceManager.getText(R.string.units_temperature_celsius).toString(),
					(float)temperature / 10));
			}
			else
			{
				PowerTemperature.setText(String.format(
						ResourceManager.getText(R.string.units_temperature_fahrenheit).toString(),
						(float)temperature / 10 * 9 / 5 + 32));
			}
		}
	};
    
}
